package main

import (
    "fmt"
    "net"
    "sync"
    "io"
    "time"
)

type Server struct{
    Ip string
    Port int

    //在线用户列表
    OnlineMap map[string]*User
    mapLock sync.RWMutex

    //消息广播channel
    Message chan string
}

//创建server接口
func NewServer(ip string, port int) *Server {
    server := &Server{
        Ip:         ip,
        Port:       port,
        OnlineMap:  make(map[string]*User),
        Message:    make(chan string),
    }
    return server
}

//连接成功的业务
func (this *Server) Hanlder(conn net.Conn){
    //fmt.Println("连接建立成功")
    user := NewUser(conn,this)

    //用户上线
    user.Online()

    //监听用户消息活跃channel
    isActive := make(chan bool)

    //接收用户消息
    go func(){
         buf := make([]byte,4096)
         for {
            n, err := conn.Read(buf)
            if n == 0 {
                //用户下线
                user.Offline()
                return
            }

            if err != nil && err != io.EOF {
                fmt.Println("Conn Read err:",err)
                return
            }
            //提取用户的消息（去除"\n"），截取0至n-1
            msg := string(buf[:n-1])

            //用户处理消息
            user.DoMessage(msg)

            //用户发消息，代表活跃
            isActive <- true
         }
     }()

    //当前hanlder阻塞
    for {
        select{
            case <-isActive:
                //用户活跃,激活select，重置定时器

            case <-time.After(time.Second * 1200):
                //超时不活跃，踢出下线
                user.SendMsg("长时间不操作，强制下线\n")

                //销毁用户资源
                close(user.C)

                //关闭连接
                conn.Close()

                //退出当前hanlder
                return  //或者runtime.Goexit()
        }
    }
}

//广播消息
func (this *Server)BroadCast(user *User, msg string){
    sendMsg := "[" + user.Addr + "]" + user.Name + "]" + msg
    this.Message <- sendMsg
}

//监听Message广播消息channel，有消息就发给在线User
func (this *Server) ListenerMessager(){
    for {
        msg := <-this.Message

        this.mapLock.Lock()
        for _,cli := range this.OnlineMap{
            cli.C <- msg
        }
        this.mapLock.Unlock()
    }
}

//启动服务器接口
func (this *Server) Start(){
    //socket listen 127.0.0.1:8888
    listener,err := net.Listen("tcp",fmt.Sprintf("%s:%d",this.Ip,this.Port))
    if err != nil{
        fmt.Println("net.listen err:",err)
        return
    }

    //socket close
    defer listener.Close()

    //启动监听Message
    go this.ListenerMessager()

    for {
        //accept
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("listener.Accept err:",err)
            return
        }

        //do hanlder
        go this.Hanlder(conn)
    }
}